package com.xbell.dahua.demo.camera.dahua;

import com.netsdk.lib.NetSDKLib;
import com.sun.jna.Pointer;
import com.xbell.dahua.demo.utils.FfmpegUtil;
import lombok.extern.slf4j.Slf4j;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

import static com.xbell.dahua.demo.controller.WebCameraController.filename;

/**
 * 实时预览数据回调函数--扩展(pBuffer内存由SDK内部申请释放)
 */
@Slf4j
public class CbfRealDataCallBackEx implements NetSDKLib.fRealDataCallBackEx {

    private final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1);

    private AtomicBoolean isConvert = new AtomicBoolean(false);

    private CbfRealDataCallBackEx() {
    }

    private static class CallBackHolder {
        private static final CbfRealDataCallBackEx instance = new CbfRealDataCallBackEx();
    }

    public static CbfRealDataCallBackEx getInstance() {
        return CallBackHolder.instance;
    }

    @Override
    public void invoke(NetSDKLib.LLong lRealHandle, int dwDataType, Pointer pBuffer,
                       int dwBufSize, int param, Pointer dwUser) {
//        log.info("handle: {}, data type: {}, buf len: {}", lRealHandle.longValue(), dwDataType, dwBufSize);
        if (0 != lRealHandle.longValue()) {
            if (dwDataType == 1002) { // ts
//            if (dwDataType == 1005) { // flv
                byte[] buffer = pBuffer.getByteArray(0, dwBufSize);
//                if (dwBufSize >= 5 &&
//                        buffer[0] == 0x46 &&  // 'F'
//                        buffer[1] == 0x4C &&  // 'L'
//                        buffer[2] == 0x56) {  // 'V'
//
//                    log.info("flv data");
//                    // 确认是FLV流
//                }
                // 写入文件
                try {
                    Files.write(Paths.get("stream/test.ts"), buffer,
                            StandardOpenOption.CREATE,
                            StandardOpenOption.APPEND);

                    if (isConvert.compareAndSet(false, true)) {
//                        FfmpegUtil.convertToHls("test.ts", "test.m3u8");
                        executor.schedule(() -> FfmpegUtil.convertToHls("test.ts", "test.m3u8"), 1, TimeUnit.SECONDS);
                    }
                } catch (Exception e) {
                    log.error("写入文件异常: {}", e.getMessage(), e);
                }

                // 通过 websocket 转发视频流给前端
//                byte[] filtered = filterFlvAudioTags(buffer);
//                FlvWebSocketHandler.broadcastFlv(buffer);
            }
        }
    }


}